﻿using System;
using System.Collections.Generic;
using UnityEngine;


public static class AgentActionFactory
{
    public enum E_Type
    {
        E_IDLE,             //待机
        E_MOVE,             //移动AgentActionMove
        E_GOTO,             //跳转移动（比如寻路到某点）
		E_COMBAT_MOVE,      //战斗移动（战斗状态下的移动）
		E_ATTACK,           //攻击（基础攻击）
		E_ATTACK_ROLL,      //翻滚攻击
		E_ATTACK_JUMP,      //跳跃攻击
		E_ATTACK_WHIRL,     //回旋攻击（旋风斩等）
		E_INJURY,           //受伤（被击中）
		E_DAMAGE_BLOCKED,   //格挡成功（伤害被挡住）
		E_BLOCK,            //正在格挡（举盾状态）
		E_ROLL,             //翻滚（闪避动作）
		E_INCOMMING_ATTACK, //敌方攻击预警（可用于AI判断）
		E_WEAPON_SHOW,      //展示武器（抽出、切换武器等）
		Rotate,             //旋转朝向（可能用于镜头或角色转身）
		E_USE_LEVER,        //使用机关（拉杆、开门）
		E_PLAY_ANIM,        //播放指定动画（可能为剧情演出）
		E_PLAY_IDLE_ANIM,   //播放特殊待机动画（坐下、打哈欠）
		E_DEATH,            //死亡
		E_KNOCKDOWN,        //倒地（被击倒）
		Teleport,           //传送（瞬移）
		E_COUNT             //状态数量（通常用于枚举末尾计数）
	}

    static private Queue<AgentAction>[] m_UnusedActions = new Queue<AgentAction>[(int)E_Type.E_COUNT];

    // DEBUG !!!!!!!
    static private List<AgentAction> m_ActionsInAction = new List<AgentAction>();


    static AgentActionFactory()
    {
        for (E_Type i = 0; i < E_Type.E_COUNT; i++)
        {
            m_UnusedActions[(int)i] = new Queue<AgentAction>();
            //maybe we could precreate few of them ?
        }
    }

    static public AgentAction Create(E_Type type)
    {
        int index = (int)type;

        AgentAction a;
        if (m_UnusedActions[index].Count > 0)
        {
            a = m_UnusedActions[index].Dequeue();
        }
        else
        {
            switch (type)
            {
                case E_Type.E_IDLE:
                    a = new AgentActionIdle();
                    break;
                case E_Type.E_MOVE:
                    a = new AgentActionMove();
                    break;
                case E_Type.E_GOTO:
                    a = new AgentActionGoTo();
                    break;
                case E_Type.E_COMBAT_MOVE:
                    a = new AgentActioCombatMove();
                    break;
                case E_Type.E_ATTACK:
                    a = new AgentActionAttack();
                    break;
                case E_Type.E_ATTACK_ROLL:
                    a = new AgentActionAttackRoll();
                    break;
                case E_Type.E_ATTACK_WHIRL:
                    a = new AgentActionAttackWhirl();
                    break;
                case E_Type.E_INJURY:
                    a = new AgentActionInjury();
                    break;
                case E_Type.E_DAMAGE_BLOCKED:
                    a = new AgentActionDamageBlocked();
                    break;
                case E_Type.E_BLOCK:
                    a = new AgentActionBlock();
                    break;
                case E_Type.E_ROLL:
                    a = new AgentActionRoll();
                    break;
                case E_Type.E_INCOMMING_ATTACK:
                    a = new AgentActionIncommingAttack();
                    break;
                case E_Type.E_WEAPON_SHOW:
                    a = new AgentActionWeaponShow();
                    break;
                case E_Type.Rotate:
                    a = new AgentActionRotate();
                    break;
                case E_Type.E_USE_LEVER:
                    a = new AgentActionUseLever();
                    break;
                case E_Type.E_PLAY_ANIM:
                    a = new AgentActionPlayAnim();
                    break;
                case E_Type.E_PLAY_IDLE_ANIM:
                    a = new AgentActionPlayIdleAnim();
                    break;
                case E_Type.E_DEATH:
                    a = new AgentActionDeath();
                    break;
                case E_Type.E_KNOCKDOWN:
                    a = new AgentActionKnockdown();
                    break;
                case E_Type.Teleport:
                    a = new AgentActionTeleport();
                    break;
                default:
                    Debug.LogError("no AgentAction to create");
                    return null;
            }
        }
        a.Reset();
        a.SetActive();

        // DEBUG !!!!!!
        m_ActionsInAction.Add(a);
        return a;
    }

    static public void Return(AgentAction action)
    {
        action.SetUnused();

        m_UnusedActions[(int)action.Type].Enqueue(action);
        //DEBUG SHIT
        m_ActionsInAction.Remove(action);
    }

    static public void Report()
    {
        Debug.Log("Action Factory m_ActionsInAction " + m_ActionsInAction.Count);
        for (int i = 0; i < m_ActionsInAction.Count; i++)
            Debug.Log(m_ActionsInAction[i].Type);
    }
}

